﻿using Core.Extension;
using PacketDotNet.Utils;
using Services.Equ.PcapCommunication.Abstract;
using SharpPcap;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;

namespace Services.Equ.PcapCommunication
{
    /// <summary>
    /// 建立pcap链接处理类
    /// </summary>
    public class ConnectCommunication : AbstractPcapCommunication<bool>
    {
        public ConnectCommunication(PhysicalAddress destinationMac, string password, ILiveDevice device) : base(destinationMac, password, device)
        {
            DcpType = 0x10001;
            OptionType = 0x10001;
            ReciveBreak = 1;
        }
        public override bool IsResponse(byte[] bytes)
        {
            if (base.IsResponse(bytes))
            {
                return bytes[19] == 2 && bytes[21] == 1;
            }
            else
            {
                return false;
            }
        }

        public override bool ConvertData2Result(byte[] bytes)
        {
            var status = bytes[59];
            if (status == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 生成链接签名方法
        /// </summary>
        /// <returns></returns>
        protected byte[] CreateLinkSignData()
        {
            byte[] data =
            [
                .. DestinationMac.GetAddressBytes(),
                .. Device.GetDeviceMacAddr()!.GetAddressBytes(),
                .. UUID,
                .. BitConverter.GetBytes(SeqId).Reverse(),
                .. BitConverter.GetBytes(OperationId).Reverse(),
                .. BitConverter.GetBytes(SeqId).Reverse(),
                .. Encoding.UTF8.GetBytes(Password),
            ];
            return data;
        }

        public override byte[] CreateBlockData()
        {
            var signData = CreateLinkSignData();
            var crcData = Crc32(signData);
            return crcData;
            //return [
            //    ..BitConverter.GetBytes(OptionType).Reverse(),
            //    ..BitConverter.GetBytes(crcData.Length).Reverse(),
            //    ..crcData
            //];
        }
        /// <summary>
        /// crc32校验
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        protected byte[] Crc32(byte[] data)
        {
            Crc32 crc = new Crc32();
            return crc.ComputeHash(data);
        }
    }
}
